#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>

//#include <ncurses.h>
//#include <menu.h>


#include "read_fan_temperature.h"
#include "terminal_stdscr.h"
#include "../ec_it8733_inc/ec_it8733_dev.h"

#include "../ttyrw_lib/ttyrw_lib.h"

#include "ec_it8733_rw.h"

//#define DBG_UART_PRT
#include "../ec_it8733_inc/dbg_prt.h"

#if 0
int const_nMaxColumn()
{
	return (const_nMaxCell*3-2);
}
#endif
#define uint8_t unsigned char

typedef struct 
{
	uint8_t D0:1;  //bit 0
	uint8_t D1:1;  //bit 1
	uint8_t D2:1;
	uint8_t D3:1;
	uint8_t D4:1;
	uint8_t D5:1;
	uint8_t D6:1;
	uint8_t D7:1;  //bit 7
	// low 
}defParaDataRegBits;

typedef struct 
{
	union
	{
		defParaDataRegBits bits;
		uint8_t u8;
	};
}defParaDataRegByte;

typedef struct 
{
	uint8_t STB:1;  //bit 0
	uint8_t AFD:1;  //bit 1
	uint8_t SLIN:1;
	uint8_t INIT:1;
	uint8_t IRQE:1;
	uint8_t PDDIR:1;
	uint8_t resv:2;  //bit 7-6
	// low 
}defParaCtrlRegBits;

typedef struct 
{
	union
	{
		defParaCtrlRegBits bits;
		uint8_t u8;
	};
}defParaCtrlRegByte;

typedef struct 
{
	uint8_t TMOUT:1;  //bit 0
	uint8_t RESV:2;
	uint8_t ERR:1;
	uint8_t SLCT:1;
	uint8_t PE:1;
	uint8_t ACK:1;  //bit 6
	uint8_t BUSY:1;  //bit 7
	// low 
}defParaStatusRegBits;

typedef struct 
{
	union
	{
		defParaStatusRegBits bits;
		uint8_t u8;
	};
}defParaStatusRegByte;

const unsigned char const_u8ParaAddrOffData=0;
const unsigned char const_u8ParaAddrOffStat=1;
const unsigned char const_u8ParaAddrOffCtrl=2;

extern EN_RUN_STATE_TYPE en_run_state;
void *thr_fn(void *arg);

static void disp_menu();

void disp_menu()
{
	printf( "  3     test parallel port\n" );

	#if 0
	dbg_rn_prt( "  3     read chip id" );
	dbg_rn_prt( "  4     read base address of parallel port" );
	dbg_rn_prt( "  5     start the thread read cpu temperature and fan rpm" );
	dbg_rn_prt( "  6     stop the thread read cpu temperature and fan rpm" );
	dbg_rn_prt( "  8     only once read cpu temperature and fan rpm" );
	#endif
	printf( "  9     exit this program\n" );
}

int ternimal_parallel_port(void)
{	int ch;

	disp_menu();

	while(en_run_state!=RUN_STATE_EXIT)
    {
		ch = getchar();			/* If raw() hadn't been called
						 * we have to press enter before it
						 * gets to the program 		*/
		//if(ch == defKeyFMenuBgn+6 )		/* Without keypad enabled this will */
		//	printw("F7 Key pressed");/*  not get to us either	*/
						/* Without noecho() some ugly escape
						 * charachters might have been printed
						 * on screen			*/

		dbg_rn_prt( "en_run_state: %4d; ch=%d", en_run_state, ch );

#if 0
		if(ch == '3')
		{
			unsigned char chipid0;
			unsigned char chipid1;
			CEcIt8733Rw::getInstance()->get_chip_id(&chipid0, &chipid1);
			dbg_rn_prt( "chipid0 =%02X; chipid1 =%02X",chipid0, chipid1 );

		}
		else if (ch == '4')
		{
			unsigned short u16FBaseAddr;
			CEcIt8733Rw::getInstance()->get_baseaddr_parallel_port( &u16FBaseAddr );
			dbg_rn_prt( "u16FBaseAddr = 0x%04X", u16FBaseAddr );

		}

		else if (ch == '5')
		{
			unsigned char u8Data=0;
			CEcIt8733Rw::getInstance()->get_para_port_reg(1, &u8Data);
			dbg_rn_prt( "u8Data = 0x%04X", u8Data );

		}
		
		else if (ch == '6')
		{
			defParaCtrlRegByte ctrlreg;
			ctrlreg.u8=0;
			//ctrlreg.=(defParaCtrlRegByte)0;
			ctrlreg.bits.STB=1;
			dbg_file_line( "ctrlreg = 0x%04X", (uint8_t)ctrlreg.u8 );

			unsigned char u8Data;
			u8Data=0;
			CEcIt8733Rw::getInstance()->set_para_port_reg(0, u8Data);
			//usleep(100);
			CEcIt8733Rw::getInstance()->get_para_port_reg(1, &u8Data);
			dbg_file_line( "u8Data = 0x%04X", u8Data );

			u8Data=0xFF;
			CEcIt8733Rw::getInstance()->set_para_port_reg(0, u8Data);
			//usleep(100);
			CEcIt8733Rw::getInstance()->get_para_port_reg(1, &u8Data);
			dbg_file_line( "u8Data = 0x%04X", u8Data );


			u8Data=0;
			CEcIt8733Rw::getInstance()->set_para_port_reg(2, u8Data);
			CEcIt8733Rw::getInstance()->set_para_port_reg(0, 0);
			CEcIt8733Rw::getInstance()->get_para_port_reg(1, &u8Data);
			dbg_file_line( "u8Data = 0x%04X", u8Data );

			u8Data=0;
			CEcIt8733Rw::getInstance()->set_para_port_reg(2, u8Data);
			CEcIt8733Rw::getInstance()->set_para_port_reg(0, 0xFF);
			CEcIt8733Rw::getInstance()->get_para_port_reg(1, &u8Data);
			dbg_file_line( "u8Data = 0x%04X", u8Data );


			u8Data=0xFF;
			CEcIt8733Rw::getInstance()->set_para_port_reg(2, u8Data);
			CEcIt8733Rw::getInstance()->set_para_port_reg(0, 0);
			CEcIt8733Rw::getInstance()->get_para_port_reg(1, &u8Data);
			dbg_file_line( "u8Data = 0x%04X", u8Data );

			u8Data=0xFF;
			CEcIt8733Rw::getInstance()->set_para_port_reg(2, u8Data);
			CEcIt8733Rw::getInstance()->set_para_port_reg(0, 0xFF);
			CEcIt8733Rw::getInstance()->get_para_port_reg(1, &u8Data);
			dbg_file_line( "u8Data = 0x%04X", u8Data );

		}			
#endif

		if(ch == '3')
		{
			unsigned char chipid0;
			unsigned char chipid1;
			CEcIt8733Rw::getInstance()->get_chip_id(&chipid0, &chipid1);
			dbg_rn_prt( "chipid0 =%02X; chipid1 =%02X",chipid0, chipid1 );

		
			unsigned short u16FBaseAddr;
			CEcIt8733Rw::getInstance()->get_baseaddr_parallel_port( &u16FBaseAddr );
			dbg_rn_prt( "u16FBaseAddr = 0x%04X", u16FBaseAddr );

			unsigned char u8Data=0;
			CEcIt8733Rw::getInstance()->get_para_port_reg(1, &u8Data);
			dbg_rn_prt( "u8Data = 0x%04X", u8Data );

			defParaCtrlRegByte ctrlreg;
			ctrlreg.u8=0;
			defParaStatusRegByte statusreg;
			statusreg.u8=0;

			defParaDataRegByte datareg;
			datareg.u8=0;
			int i;

			for(i=0;i<4;i++)
			{
				ctrlreg.u8=0;
				ctrlreg.bits.STB=i%2;
				CEcIt8733Rw::getInstance()->set_para_port_reg(const_u8ParaAddrOffCtrl, ctrlreg.u8);
				CEcIt8733Rw::getInstance()->get_para_port_reg(const_u8ParaAddrOffStat, &statusreg.u8);
				dbg_file_line( "%d; %d; %d", statusreg.bits.SLCT, i, ctrlreg.bits.STB);
				if(ctrlreg.bits.STB == statusreg.bits.SLCT)
					break;
			}
			if(i<4)
			{
				printf( "STROBE    1-----------13 SELECT FAIL\n");
			}
			else
			{
				printf( "STROBE    1-----------13 SELECT PASS\n");
			}

			for(i=0;i<4;i++)
			{
				ctrlreg.u8=0;
				ctrlreg.bits.AFD=i%2;
				CEcIt8733Rw::getInstance()->set_para_port_reg(const_u8ParaAddrOffCtrl, ctrlreg.u8);
				CEcIt8733Rw::getInstance()->get_para_port_reg(const_u8ParaAddrOffStat, &statusreg.u8);
				dbg_file_line( "%d; %d; %d", statusreg.bits.PE, i, ctrlreg.bits.AFD);
				if(ctrlreg.bits.AFD == statusreg.bits.PE)
					break;
			}
			if(i<4)
			{
				printf( "AUTO FEED 14----------12 P.E. FAIL\n");
			}
			else
			{
				printf( "AUTO FEED 14----------12 P.E. PASS\n");
			}

			for(i=0;i<4;i++)
			{
				ctrlreg.u8=0;
				ctrlreg.bits.INIT=i%2;
				CEcIt8733Rw::getInstance()->set_para_port_reg(const_u8ParaAddrOffCtrl, ctrlreg.u8);
				CEcIt8733Rw::getInstance()->get_para_port_reg(const_u8ParaAddrOffStat, &statusreg.u8);
				dbg_file_line( "%d; %d; %d", statusreg.bits.ACK, i, ctrlreg.bits.INIT);
				if(1 == statusreg.bits.ACK)
					break;
			}
			if(i<4)
			{
				printf( "INIT      16----------10 ACK FAIL\n");
			}
			else
			{
				printf( "INIT      16----------10 ACK PASS\n");
			}

			for(i=0;i<4;i++)
			{
				ctrlreg.u8=0;
				ctrlreg.bits.INIT=i%2;
				ctrlreg.bits.SLIN=i%2;
				CEcIt8733Rw::getInstance()->set_para_port_reg(const_u8ParaAddrOffCtrl, ctrlreg.u8);
				CEcIt8733Rw::getInstance()->get_para_port_reg(const_u8ParaAddrOffStat, &statusreg.u8);
				dbg_file_line( "%d; %d; %d", statusreg.bits.BUSY, i, ctrlreg.bits.SLIN);
				if(ctrlreg.bits.SLIN != statusreg.bits.BUSY)
					break;
			}
			if(i<4)
			{
				printf( "SELECT IN 17----------11 BUSY FAIL\n");
			}
			else
			{
				printf( "SELECT IN 17----------11 BUSY PASS\n");
			}

			for(i=0;i<4;i++)
			{
				datareg.u8=0;
				datareg.bits.D0=i%2;
				
				CEcIt8733Rw::getInstance()->set_para_port_reg(const_u8ParaAddrOffData, datareg.u8);
				CEcIt8733Rw::getInstance()->get_para_port_reg(const_u8ParaAddrOffStat, &statusreg.u8);
				dbg_file_line( "%d; %d; %d", statusreg.bits.ERR, i, datareg.bits.D0);
				if(datareg.bits.D0 != statusreg.bits.ERR)
					break;
			}
			if(i<4)
			{
				printf( "D0        2-----------15 ERROR FAIL\n");
			}
			else
			{
				printf( "D0        2-----------15 ERROR PASS\n");
			}


		}			


		else if (ch == '9')
		{

			en_run_state=RUN_STATE_EXIT;
			dbg_rn_prt( "en_run_state: %4d ", en_run_state );
		}

		else if (ch == 10)  //enter
		{
			usleep(100*1000);
			disp_menu();

		}
			

	
	}

	return 0;
}


